using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Networking.Match;
using UnityEngine.Networking.Types;
using UnityEngine.SceneManagement;

public class GameNetwork : NetworkLobbyManager
{
	private class KickMsg : MessageBase
	{
	}

	private class BeginkMsg : MessageBase
	{
	}

	[HideInInspector]
	public bool IsDedicatedServer;

	[HideInInspector]
	public List<MatchInfoSnapshot> MatchListResponse;

	[HideInInspector]
	public MatchInfoSnapshot MatchSelected;

	public NetworkGameplayManager NetworkGamePlay;

	public string HostPassword = string.Empty;

	public string HostNameFillter = string.Empty;

	public bool AutoStart;

	private static short MsgKicked = 48;

	private static short MsgBegin = 49;

	protected ulong currentMatchID;

	private bool isMatchMaking;

	private List<PlayerSpawnInfo> playerWaitingSpawn;

	private bool startingServer;

	public bool IsOnLobby(string scenename = "")
	{
		if (scenename == string.Empty)
		{
			scenename = SceneManager.GetActiveScene().name;
		}
		return scenename == base.lobbyScene;
	}

	public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
	{
		if (!IsOnLobby(string.Empty))
		{
			GameObject player = Object.Instantiate(base.playerPrefab, new Vector2(0f, 0f), Quaternion.identity);
			NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
		}
		else
		{
			base.OnServerAddPlayer(conn, playerControllerId);
		}
	}

	public override void OnLobbyServerSceneChanged(string sceneName)
	{
		UnityEngine.Debug.Log("Server scene loaded, spawn all players object *" + playerWaitingSpawn.Count);
		foreach (PlayerSpawnInfo item in playerWaitingSpawn)
		{
			RequestSpawnPlayerObject(Vector3.zero, 0, item.UserID, item.PlayerName, item.CharacterIndex, item.CharacterKey, item.PlayerTeam, 0);
		}
		base.OnLobbyServerSceneChanged(sceneName);
	}

	public override void OnClientSceneChanged(NetworkConnection conn)
	{
		if (UnitZ.Hud != null)
		{
			UnitZ.Hud.ProcessPopup.SetActive(value: false);
		}
		base.OnClientSceneChanged(conn);
	}

	public override void OnServerSceneChanged(string sceneName)
	{
		if (!IsOnLobby(sceneName) && NetworkServer.active && NetworkGamePlay != null && UnitZ.NetworkGameplay == null)
		{
			GameObject obj = Object.Instantiate(NetworkGamePlay.gameObject, Vector3.zero, Quaternion.identity);
			NetworkServer.Spawn(obj);
		}
		base.OnServerSceneChanged(sceneName);
	}

	public void FindInternetMatch()
	{
		MatchListResponse = null;
		NetworkManager.singleton.StartMatchMaker();
		if (UnitZ.Hud != null)
		{
			UnitZ.Hud.ProcessPopup.SetActive(value: true);
		}
		NetworkManager.singleton.matchMaker.ListMatches(0, 50, HostNameFillter, filterOutPrivateMatchesFromResults: false, 0, 0, ((NetworkManager)this).OnMatchList);
	}

	public override void OnMatchList(bool success, string extendedInfo, List<MatchInfoSnapshot> matchList)
	{
		if (UnitZ.Hud != null)
		{
			UnitZ.Hud.ProcessPopup.SetActive(value: false);
		}
		MatchListResponse = matchList;
		if (MatchListResponse != null && success)
		{
			if (matchList.Count != 0)
			{
				UnityEngine.Debug.Log("Server lists ");
				for (int i = 0; i < MatchListResponse.Count; i++)
				{
					UnityEngine.Debug.Log("Game " + MatchListResponse[i].name + " " + MatchListResponse[i].currentSize + "/" + MatchListResponse[i].maxSize + " (Private)" + MatchListResponse[i].isPrivate);
				}
			}
			else
			{
				UnityEngine.Debug.Log("No matches in requested room!");
			}
		}
		else
		{
			UnityEngine.Debug.LogError("Couldn't connect to match maker");
		}
	}

	public void HostGame(int levelindex, bool online)
	{
		LevelPreset level = UnitZ.levelManager.GetLevel(levelindex);
		if (level == null)
		{
			return;
		}
		base.playScene = level.SceneName;
		NetworkGamePlay = level.GamePlayObject;
		isMatchMaking = online;
		startingServer = false;
		if (online)
		{
			if (UnitZ.Hud != null)
			{
				UnitZ.Hud.ProcessPopup.SetActive(value: true);
			}
			StartMatchMaker();
			NetworkManager.singleton.matchMaker.CreateMatch(matchName, (uint)base.maxConnections, matchAdvertise: true, HostPassword, string.Empty, string.Empty, 0, 0, ((NetworkManager)this).OnMatchCreate);
		}
		else
		{
			NetworkManager.singleton.StartHost();
		}
		UnityEngine.Debug.Log("Host game Max" + base.maxConnections);
	}

	public void JoinGame()
	{
		if (MainMenuManager.menu != null)
		{
			MainMenuManager.menu.SetPreviousPanel(MainMenuManager.menu.currentPanel);
		}
		if (MatchSelected != null)
		{
			if (MatchSelected.isPrivate)
			{
				UnityEngine.Debug.Log("Need password");
				if (Popup.Pop != null)
				{
					Popup.Pop.AskingPassword("need password ", delegate
					{
						Popup.Pop.PopupPasswordObject.gameObject.SetActive(value: false);
						UnityEngine.Debug.Log("Access with Password " + Popup.Pop.PopupPasswordObject.Password);
						NetworkManager.singleton.matchMaker.JoinMatch(MatchSelected.networkId, Popup.Pop.PopupPasswordObject.Password, string.Empty, string.Empty, 0, 0, ((NetworkManager)this).OnMatchJoined);
					}, delegate
					{
						LeaveMatch();
						Popup.Pop.PopupPasswordObject.gameObject.SetActive(value: false);
					});
				}
			}
			else
			{
				if (UnitZ.Hud != null)
				{
					UnitZ.Hud.ProcessPopup.SetActive(value: true);
				}
				NetworkManager.singleton.matchMaker.JoinMatch(MatchSelected.networkId, string.Empty, string.Empty, string.Empty, 0, 0, ((NetworkManager)this).OnMatchJoined);
			}
			UnityEngine.Debug.Log("Connecting to matchMaker");
		}
		else
		{
			NetworkManager.singleton.networkAddress = base.networkAddress;
			NetworkManager.singleton.networkPort = base.networkPort;
			NetworkManager.singleton.StartClient();
			UnityEngine.Debug.Log("Connecting to IP : " + base.networkAddress);
		}
	}

	public void MatchSelect(MatchInfoSnapshot match)
	{
		currentMatchID = (ulong)match.networkId;
		MatchSelected = match;
	}

	public override void OnDropConnection(bool success, string extendedInfo)
	{
		UnityEngine.Debug.Log("Game is procesed!");
		base.OnDropConnection(success, extendedInfo);
	}

	public override void OnMatchJoined(bool success, string extendedInfo, MatchInfo matchInfo)
	{
		if (UnitZ.Hud != null)
		{
			UnitZ.Hud.ProcessPopup.SetActive(value: false);
		}
		UnityEngine.Debug.Log("Connecting success " + success + " " + extendedInfo + " " + matchInfo);
		if (success)
		{
			NetworkManager.singleton.StartClient(matchInfo);
			UnityEngine.Debug.Log("Connected!");
		}
		else if (Popup.Pop != null)
		{
			Popup.Pop.Asking("Unable to connect", null, delegate
			{
			});
		}
	}

	public override void OnLobbyClientSceneChanged(NetworkConnection conn)
	{
		if (IsOnLobby(string.Empty) && MainMenuManager.menu != null)
		{
			MainMenuManager.menu.OpenPanelByName("Home");
		}
	}

	public void SetServerInfo(string status, string host)
	{
		UnityEngine.Debug.Log("Received server info " + status + " " + host);
	}

	public override void OnStartHost()
	{
		base.OnStartHost();
		UnityEngine.Debug.Log("On Start Host");
		if (MainMenuManager.menu != null)
		{
			MainMenuManager.menu.OpenPanelByName("Lobby");
		}
		SetServerInfo("Hosting", base.networkAddress);
	}

	public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
	{
		if (UnitZ.Hud != null)
		{
			UnitZ.Hud.ProcessPopup.SetActive(value: false);
		}
		UnityEngine.Debug.Log("On Match created!! " + success);
		base.OnMatchCreate(success, extendedInfo, matchInfo);
		currentMatchID = (ulong)matchInfo.networkId;
	}

	public override void OnDestroyMatch(bool success, string extendedInfo)
	{
		UnityEngine.Debug.Log("On Destroy match");
		base.OnDestroyMatch(success, extendedInfo);
		StopMatchMaker();
		StopHost();
	}

	public void RemovePlayer(PlayerLobby player)
	{
		player.RemovePlayer();
	}

	public void DestroyMatch()
	{
		if (isMatchMaking)
		{
			matchMaker.DestroyMatch((NetworkID)currentMatchID, 0, ((NetworkManager)this).OnDestroyMatch);
		}
		else
		{
			StopHost();
		}
		if (MainMenuManager.menu != null)
		{
			MainMenuManager.menu.OpenPreviousPanel();
		}
	}

	public void LeaveMatch()
	{
		MatchSelected = null;
		StopClient();
		if (isMatchMaking)
		{
			StopMatchMaker();
		}
		if (MainMenuManager.menu != null)
		{
			MainMenuManager.menu.OpenPreviousPanel();
		}
	}

	public override GameObject OnLobbyServerCreateLobbyPlayer(NetworkConnection conn, short playerControllerId)
	{
		UnityEngine.Debug.Log("On Lobby server create lobby player");
		GameObject result = Object.Instantiate(base.lobbyPlayerPrefab.gameObject);
		for (int i = 0; i < lobbySlots.Length; i++)
		{
			PlayerLobby playerLobby = lobbySlots[i] as PlayerLobby;
			if (playerLobby != null)
			{
				playerLobby.CallRpcUpdatePlayerLobby();
			}
		}
		if (ServerLog.instance != null)
		{
			ServerLog.instance.Log("Player lobby:" + conn.address + " created");
		}
		return result;
	}

	public override void OnLobbyServerPlayerRemoved(NetworkConnection conn, short playerControllerId)
	{
		UnityEngine.Debug.Log("On Lobby server remove lobby player");
		for (int i = 0; i < lobbySlots.Length; i++)
		{
			PlayerLobby playerLobby = lobbySlots[i] as PlayerLobby;
			if (playerLobby != null)
			{
				playerLobby.CallRpcUpdatePlayerLobby();
			}
		}
		if (ServerLog.instance != null)
		{
			ServerLog.instance.Log("Player lobby:" + conn.address + " removed");
		}
	}

	public override void OnLobbyServerDisconnect(NetworkConnection conn)
	{
		UnityEngine.Debug.Log("On lobby disconnect");
		if (ServerLog.instance != null)
		{
			ServerLog.instance.Log("Player lobby:" + conn.address + " disconnected");
		}
		for (int i = 0; i < lobbySlots.Length; i++)
		{
			PlayerLobby playerLobby = lobbySlots[i] as PlayerLobby;
			if (playerLobby != null)
			{
				playerLobby.CallRpcUpdatePlayerLobby();
			}
		}
	}

	public override void OnLobbyServerPlayersReady()
	{
		if (AutoStart)
		{
			StartServerGame();
		}
	}

	public int GetLobbyPlayerCount()
	{
		int num = 0;
		for (int i = 0; i < lobbySlots.Length; i++)
		{
			if (lobbySlots[i] != null)
			{
				num++;
			}
		}
		return num;
	}

	public void AssignPlayersToSpawn(PlayerLobby[] players)
	{
		playerWaitingSpawn = new List<PlayerSpawnInfo>();
		for (int i = 0; i < players.Length; i++)
		{
			if (players[i].PlayerID != string.Empty)
			{
				PlayerSpawnInfo playerSpawnInfo = new PlayerSpawnInfo();
				playerSpawnInfo.CharacterIndex = players[i].CharacterIndex;
				playerSpawnInfo.PlayerName = players[i].playerName;
				playerSpawnInfo.PlayerTeam = players[i].playerTeam;
				playerSpawnInfo.UserID = players[i].PlayerID;
				playerSpawnInfo.CharacterKey = string.Empty;
				playerWaitingSpawn.Add(playerSpawnInfo);
			}
		}
	}

	public bool StartServerGame()
	{
		bool flag = true;
		for (int i = 0; i < lobbySlots.Length; i++)
		{
			if (lobbySlots[i] != null && !lobbySlots[i].readyToBegin)
			{
				UnityEngine.Debug.Log("Can't Start!, Someone is not ready");
				flag = false;
			}
		}
		if (flag && !startingServer)
		{
			StartCoroutine(ServerCountdownCoroutine());
			if (UnitZ.Hud != null)
			{
				UnitZ.Hud.ProcessPopup.SetActive(value: true);
			}
		}
		return flag;
	}

	public IEnumerator ServerCountdownCoroutine()
	{
		startingServer = true;
		float remainingTime = 1f;
		int floorTime = Mathf.FloorToInt(remainingTime);
		while (remainingTime > 0f)
		{
			yield return null;
			remainingTime -= Time.deltaTime;
			int newFloorTime = Mathf.FloorToInt(remainingTime);
			if (newFloorTime == floorTime)
			{
				continue;
			}
			floorTime = newFloorTime;
			if (ServerLog.instance != null)
			{
				ServerLog.instance.Log("Starting match.." + floorTime);
			}
			for (int i = 0; i < lobbySlots.Length; i++)
			{
				if (lobbySlots[i] != null)
				{
					(lobbySlots[i] as PlayerLobby).CallRpcUpdateCountdown(floorTime);
				}
			}
		}
		for (int j = 0; j < lobbySlots.Length; j++)
		{
			if (lobbySlots[j] != null)
			{
				(lobbySlots[j] as PlayerLobby).CallRpcUpdateCountdown(0);
				Begin(lobbySlots[j].connectionToClient);
			}
		}
		startingServer = false;
		if (UnitZ.Hud != null)
		{
			UnitZ.Hud.ProcessPopup.SetActive(value: false);
		}
		ServerChangeScene(base.playScene);
	}

	public override void OnClientConnect(NetworkConnection conn)
	{
		base.OnClientConnect(conn);
		conn.RegisterHandler(MsgKicked, KickedMessageHandler);
		conn.RegisterHandler(MsgBegin, BeginMessageHandler);
		if (!NetworkServer.active)
		{
			if (MainMenuManager.menu != null)
			{
				MainMenuManager.menu.OpenPanelByName("Lobby");
			}
			SetServerInfo("Client", base.networkAddress);
		}
		if (ServerLog.instance != null)
		{
			ServerLog.instance.Log(" Client:" + conn.address + " connected");
		}
	}

	public override void OnClientDisconnect(NetworkConnection conn)
	{
		UnityEngine.Debug.Log("on client disconnected");
		if (MainMenuManager.menu != null)
		{
			MainMenuManager.menu.OpenPanelByName("Home");
		}
		if (UnitZ.Hud != null)
		{
			UnitZ.Hud.ProcessPopup.SetActive(value: false);
		}
		if (ServerLog.instance != null)
		{
			ServerLog.instance.Log(conn.address + " disconnected");
		}
		base.OnClientDisconnect(conn);
	}

	public override void OnServerDisconnect(NetworkConnection conn)
	{
		if (ServerLog.instance != null)
		{
			ServerLog.instance.Log(" Client:" + conn.address + " disconnected");
		}
		UnityEngine.Debug.Log("on server disconnected");
		base.OnServerDisconnect(conn);
	}

	public override void OnStopHost()
	{
		if (UnitZ.Hud != null)
		{
			UnitZ.Hud.ProcessPopup.SetActive(value: false);
		}
		if (UnitZ.dedicatedManager != null)
		{
			UnitZ.dedicatedManager.OnDisconnect();
		}
		base.OnStopHost();
	}

	public override void OnStopServer()
	{
		if (UnitZ.Hud != null)
		{
			UnitZ.Hud.ProcessPopup.SetActive(value: false);
		}
		if (UnitZ.dedicatedManager != null)
		{
			UnitZ.dedicatedManager.OnDisconnect();
		}
		base.OnStopServer();
	}

	public override void OnClientError(NetworkConnection conn, int errorCode)
	{
		UnityEngine.Debug.Log("Cient error : " + errorCode.ToString());
	}

	public void OnPlayersNumberModified(int count)
	{
		int num = 0;
		foreach (PlayerController localPlayer in ClientScene.localPlayers)
		{
			num += ((localPlayer != null && localPlayer.playerControllerId != -1) ? 1 : 0);
		}
	}

	public void KickPlayer(NetworkConnection conn)
	{
		conn.Send(MsgKicked, new KickMsg());
	}

	public void Begin(NetworkConnection conn)
	{
		conn.Send(MsgBegin, new BeginkMsg());
	}

	public void KickedMessageHandler(NetworkMessage netMsg)
	{
		UnityEngine.Debug.Log("Kicked by Server");
		netMsg.conn.Disconnect();
	}

	public void BeginMessageHandler(NetworkMessage netMsg)
	{
		UnityEngine.Debug.Log("Game is begin..");
		SendMessage("OnGameIsBegin", SendMessageOptions.DontRequireReceiver);
	}

	public void Disconnect()
	{
		MatchSelected = null;
		if (NetworkServer.connections.Count > 0)
		{
			NetworkManager.singleton.StopHost();
		}
		else
		{
			NetworkManager.singleton.StopClient();
		}
	}

	public void RequestSpawnPlayerObject(Vector3 position, int connectid, string userid, string usename, int characterindex, string characterkey, byte team, int spawnpoint)
	{
		GameObject gameObject = UnitZ.playerManager.InstantiatePlayer(connectid, userid, usename, characterkey, characterindex, team, spawnpoint);
		if (!(gameObject == null))
		{
			NetworkServer.Spawn(gameObject);
			gameObject.GetComponent<CharacterSystem>().NetworkNetID = connectid;
			gameObject.GetComponent<CharacterSystem>().CallCmdOnSpawned(gameObject.transform.position);
		}
	}

	public void RequestSpawnPlayer(Vector3 position, int connectid, string userid, string usename, int characterindex, string characterkey, byte team, int spawnpoint, NetworkConnection conn)
	{
		GameObject gameObject = UnitZ.playerManager.InstantiatePlayer(connectid, userid, usename, characterkey, characterindex, team, spawnpoint);
		if (!(gameObject == null))
		{
			gameObject.GetComponent<CharacterSystem>().NetworkNetID = connectid;
			NetworkServer.ReplacePlayerForConnection(conn, gameObject, 0);
			gameObject.GetComponent<CharacterSystem>().CallCmdOnSpawned(gameObject.transform.position);
			UnityEngine.Debug.Log("Spawn player Net ID" + connectid + " info " + characterindex + " key " + characterkey);
		}
	}

	public GameObject RequestAuthorizedCharacter(string userID, int connectID, NetworkConnection conn)
	{
		CharacterSystem[] array = Object.FindObjectsOfType<CharacterSystem>();
		for (int i = 0; i < array.Length; i++)
		{
			if (array[i] != null && array[i].UserID != string.Empty && array[i].UserID == userID)
			{
				array[i].NetworkNetID = connectID;
				NetworkServer.ReplacePlayerForConnection(conn, array[i].gameObject, 0);
				UnityEngine.Debug.Log("Player Authorized " + conn.connectionId);
				return array[i].gameObject;
			}
		}
		return null;
	}

	public GameObject RequestSpawnObject(GameObject gameobj, Vector3 position, Quaternion rotation)
	{
		GameObject gameObject = Object.Instantiate(gameobj, position, rotation);
		NetworkServer.Spawn(gameObject);
		return gameObject;
	}

	public GameObject RequestSpawnItem(GameObject gameobj, int numtag, int num, Vector3 position, Quaternion rotation)
	{
		GameObject gameObject = Object.Instantiate(gameobj, position, rotation);
		ItemData component = gameObject.GetComponent<ItemData>();
		component.SetupDrop(numtag, num);
		NetworkServer.Spawn(gameObject);
		return gameObject;
	}

	public GameObject RequestSpawnBackpack(GameObject gameobj, string backpackdata, Vector3 position, Quaternion rotation)
	{
		GameObject gameObject = Object.Instantiate(gameobj, position, rotation);
		ItemBackpack component = gameObject.GetComponent<ItemBackpack>();
		component.SetDropItem(backpackdata);
		NetworkServer.Spawn(gameObject);
		return gameObject;
	}
}
